/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.aaron.platform.service;

import com.aaron.platform.dao.IMotorBookDao;
import com.aaron.platform.dao.IMotorInfoDao;
import com.aaron.platform.dao.PageInfo;
import com.aaron.platform.entity.WlbMotorBook;
import com.aaron.platform.entity.WlbMotorInfo;
import com.aaron.platform.exceptions.MotorBookExistsException;
import com.aaron.platform.exceptions.MotorInfoExistsException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;

/**
 * 车辆管理实现类
 * @author aaronbamboo
 */
public class MotorInfoMgrImp implements IMotorInfoMgr {

    private IMotorInfoDao motorInfoDao;
    
    private IMotorBookDao motorBookDao;

    public void setMotorBookDao(IMotorBookDao motorBookDao) {
        this.motorBookDao = motorBookDao;
    }

    public void setMotorInfoDao(IMotorInfoDao motorInfoDao) {
        this.motorInfoDao = motorInfoDao;
    }

    public WlbMotorInfo findById(Integer motorId) {
        return motorInfoDao.findById(motorId);
    }

    public PageInfo findByCondition(Properties condition, int startIndex, int pageSize) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(WlbMotorInfo.class);
        if (condition != null && !condition.isEmpty()) {
            
            // 归属中心
            String domainId = condition.getProperty(WlbMotorInfo.PROPERTY_DOMAIN_ID);
            if (domainId != null && Integer.valueOf(domainId).intValue() != 0 ) {
                detachedCriteria = detachedCriteria.add(Expression.eq(WlbMotorInfo.PROPERTY_DOMAIN_ID,
                        Integer.valueOf(domainId).intValue()));
            }
            
             // 驾驶员
            String driverName = condition.getProperty(WlbMotorInfo.PROPERTY_DRIVER_NAME);
            if (driverName != null && StringUtils.isNotEmpty(driverName)) {
                detachedCriteria = detachedCriteria.add(Expression.ilike(WlbMotorInfo.PROPERTY_DRIVER_NAME,
                        driverName));
            }
            
             // 车牌号
            String motorNumber = condition.getProperty(WlbMotorInfo.PROPERTY_MOTOR_NUMBER);
            if (motorNumber != null && StringUtils.isNotEmpty(motorNumber)) {
                detachedCriteria = detachedCriteria.add(Expression.ilike(WlbMotorInfo.PROPERTY_MOTOR_NUMBER,
                        motorNumber));
            }
        }
        return motorInfoDao.findPageByCriteria(detachedCriteria, startIndex, pageSize);
    }

    public PageInfo findByConditionWithBooks(Properties condition, int startIndex, int pageSize) {
        
        //  查询车辆预约信息
        PageInfo<WlbMotorInfo> motorPage = findByCondition(condition, startIndex, pageSize);
        List<WlbMotorInfo> motorInfos = motorPage.getItems();
        for (WlbMotorInfo motorInfo : motorInfos) {
            Properties bookConditions = new Properties();
            bookConditions.setProperty(WlbMotorBook.PROPERTY_MOTOR_ID, motorInfo.getMotorId().toString());
            bookConditions.setProperty(WlbMotorBook.PROPERTY_BOOK_DATE_FROM, condition.getProperty(WlbMotorBook.PROPERTY_BOOK_DATE_FROM));
            bookConditions.setProperty(WlbMotorBook.PROPERTY_BOOK_DATE_TO, condition.getProperty(WlbMotorBook.PROPERTY_BOOK_DATE_TO));
            List<WlbMotorBook> motorBooks = findBooksByCondition(bookConditions);
            motorInfo.setWlbMotorBooks(motorBooks);
        }
        // 刷选预约信息
        List<WlbMotorInfo> filteredMotorInfos = null; 
        if (condition != null && !condition.isEmpty()) {   
            String isBooked = condition.getProperty(WlbMotorInfo.PROPERTY_IS_BOOKED);
            if (isBooked != null) {
                filteredMotorInfos = new ArrayList<WlbMotorInfo>();
                if (Integer.valueOf(isBooked).intValue() == WlbMotorInfo.INT_NOT_BOOKED) { // 未预约
                    for (WlbMotorInfo motorInfo : motorInfos) {
                        if(!motorInfo.isBooked()) {
                            filteredMotorInfos.add(motorInfo);
                        }
                    }
                } else if (Integer.valueOf(isBooked).intValue() == WlbMotorInfo.INT_IS_BOOKED)  {// 预约
                    for (WlbMotorInfo motorInfo : motorInfos) {
                        if(motorInfo.isBooked()) {
                            filteredMotorInfos.add(motorInfo);
                        }
                    }
                }
            }
        }
        // 分页
        List<WlbMotorInfo> pagedMotorInfos = new ArrayList<WlbMotorInfo>();
        if (filteredMotorInfos != null) {
            for(int i = startIndex; i < startIndex + pageSize; i++) {
                pagedMotorInfos.add(filteredMotorInfos.get(i));
                if (i >= filteredMotorInfos.size()) {
                    break;
                } 
            }
            motorPage.setItems(pagedMotorInfos);
            motorPage.setTotalCount(filteredMotorInfos.size());   
        } 
        return motorPage;   
    }

    public void addMotorInfo(WlbMotorInfo wlbMotorInfo) throws MotorInfoExistsException {
        Properties conditions = new Properties();
        conditions.setProperty(WlbMotorInfo.PROPERTY_MOTOR_NUMBER, wlbMotorInfo.getMotorNum());
        PageInfo pageInfo = findByCondition(conditions, 0, 10);
        if (pageInfo.getTotalCount() > 0) {
            throw new MotorInfoExistsException();
        }
        motorInfoDao.save(wlbMotorInfo);
    }

    public void updateMotorInfo(WlbMotorInfo wlbMotorInfo) throws MotorInfoExistsException {
        
        // 车牌号码不能和其他车辆冲突
        Properties conditions = new Properties();
        conditions.setProperty(WlbMotorInfo.PROPERTY_MOTOR_NUMBER, wlbMotorInfo.getMotorNum());
        PageInfo pageInfo = findByCondition(conditions, 0, 10);
        if (pageInfo.getTotalCount() > 0) {
            WlbMotorInfo secondMotorInfo = (WlbMotorInfo) pageInfo.getItems().get(0);
            if (secondMotorInfo.getMotorId().intValue() != wlbMotorInfo.getMotorId().intValue()) {
                throw new MotorInfoExistsException();
            }
        }
        motorInfoDao.merge(wlbMotorInfo);
    }

    public void removeMotorInfo(Integer motorId) {
        
        // 删除车辆预订信息
        removeBookInfoByMotorId(motorId);
        
        // 删除车辆信息
        motorInfoDao.removeById(motorId);
    }

    public void addBookInfo(WlbMotorBook motorBook) throws MotorBookExistsException {
        
        // 检查是否已经被预订
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(WlbMotorBook.class);
        detachedCriteria.add(Expression.eq(WlbMotorBook.PROPERTY_MOTOR_ID, motorBook.getWlbMotorInfo().getMotorId()));
        detachedCriteria.add(Expression.eq(WlbMotorBook.PROPERTY_BOOK_DATE, motorBook.getBookDate()));
        List<WlbMotorBook> motorBookList = motorBookDao.findByCriteria(detachedCriteria);
        if (motorBookList != null && motorBookList.size() > 0) {
            for (WlbMotorBook book : motorBookList) {
                if (book.getBookStyle() == motorBook.getBookStyle()) {
                    throw new MotorBookExistsException();
                }
            }
        }
        
        // 添加预约
        motorBookDao.save(motorBook);
    }

    public void updateBookInfo(WlbMotorBook motorBook) throws MotorBookExistsException {
        
        // 检查是否有冲突
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(WlbMotorBook.class);
        detachedCriteria.add(Expression.eq(WlbMotorBook.PROPERTY_MOTOR_ID, motorBook.getWlbMotorInfo().getMotorId()));
        detachedCriteria.add(Expression.eq(WlbMotorBook.PROPERTY_BOOK_DATE, motorBook.getBookDate()));
        detachedCriteria.add(Expression.ne(WlbMotorBook.PROPERTY_BOOK_ID, motorBook.getBookId()));
        List<WlbMotorBook> motorBookList = motorBookDao.findByCriteria(detachedCriteria);
        if (motorBookList != null && motorBookList.size() > 0) {
            throw new MotorBookExistsException();
        }
        
        // 更新 预约
        motorBookDao.update(motorBook);
    }

    public void removeBookInfo(Integer bookId) {
        this.motorBookDao.removeById(bookId);
    }
    
    /**
     * 查询预约信息（车辆ID，使用人，使用日期）
     * @param condition
     * @return 
     */
    public List<WlbMotorBook> findBooksByCondition(Properties condition) {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(WlbMotorBook.class);
        if (condition != null && !condition.isEmpty()) {
            try {
                // 车辆ID
                Integer motorId = Integer.valueOf(condition.getProperty(WlbMotorBook.PROPERTY_MOTOR_ID));
                if (motorId != null && motorId.intValue() != 0 ) {
                    detachedCriteria = detachedCriteria.add(Expression.eq(WlbMotorBook.PROPERTY_MOTOR_ID,
                            motorId));
                }
                
                // 使用人
                String bookUser = condition.getProperty(WlbMotorBook.PROPERTY_BOOK_USER);
                if (bookUser != null && StringUtils.isNotEmpty(bookUser)) {
                    detachedCriteria = detachedCriteria.add(Expression.ilike(WlbMotorBook.PROPERTY_BOOK_USER,
                            bookUser));
                }
                
                // 使用日期
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                Date bookStartDate = condition.getProperty(WlbMotorBook.PROPERTY_BOOK_DATE_FROM) == 
                        null ? null : df.parse(condition.getProperty(WlbMotorBook.PROPERTY_BOOK_DATE_FROM));
                Date bookEndDate = condition.getProperty(WlbMotorBook.PROPERTY_BOOK_DATE_TO) == 
                        null ? null : df.parse(condition.getProperty(WlbMotorBook.PROPERTY_BOOK_DATE_TO));
                detachedCriteria = detachedCriteria.add(Expression.between(WlbMotorBook.PROPERTY_BOOK_DATE, bookStartDate, bookEndDate));
            } catch (ParseException ex) {
                Logger.getLogger(MotorInfoMgrImp.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return motorBookDao.findByCriteria(detachedCriteria);
    }

    private void removeBookInfoByMotorId(Integer motorId) {
        Properties conditions = new Properties();
        conditions.setProperty(WlbMotorBook.PROPERTY_MOTOR_ID, String.valueOf(motorId));
        List<WlbMotorBook> wlbMotorBooks = findBooksByCondition(conditions);
        motorBookDao.removeAll(wlbMotorBooks);
    }
    
}
